#define  _CRT_SECURE_NO_WARNINGS 1
//#include"head.h"

//int main()
//{
//	int a = 10;
//    printf("%zd\n", sizeof(a));
//    printf("%zd\n", sizeof(int));
//    printf("%zd\n", sizeof a);
//    printf("%zd\n", sizeof (a+2));//表达式也可以
//    /*
//    sizeof 计算变量所占内存空间大小的，单位是字节，如果操作数是类型的话，计算的是使用类
//    型创建的变量所占内存空间的大小。
//    sizeof 只关注占用内存空间的大小，不在乎内存中存放什么数据。
//    */
//
//	return 0;
//}

//int main()
//{
//	/*
//	统计的是从 strlen 函数的参数 str 中这个地址开始向后，\0 之前字符串中字符的个数。
//	strlen 函数会一直向后找\0 字符，直到找到为止，所以可能存在越界查找。
//	*/
//    char str1[] = "hello";
//	char str2[] = {'h', 'e', 'l', 'l', 'o'};
//    printf("%d\n", strlen(str1));
//	printf("%d\n", strlen(str2));//随机值
//	printf("%p\n", str1);
//	printf("%p\n", str2);
//
//	return 0;
//}

//========================================================================================================

//数组名的理解：
//1、数组名是数组首元素的地址
//但有两个例外：
//1、sizeof(数组名),数组名单独放在sizeof内部,这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节。
//2、&数组名,这里的数组名表示整个数组,取出的是整个数组的地址

//一维数组
//int main()
//{
//	int a[] = {1, 2, 3, 4};
//    printf("sizeof(a)\t= %zd\n", sizeof(a));//4 * 4 = 16
//	printf("sizeof(a + 0)\t= %zd\n", sizeof(a + 0));//a就是首元素的地址,a+0还是首元素的地址,计算的是地址的大小:4/8
//	printf("sizeof(*a)\t= %zd\n", sizeof(*a));//a是首元素的地址，*a就是首元素，计算首元素的大小
//	printf("sizeof(a + 1)\t= %zd\n", sizeof(a + 1));//a就是首元素的地址,a+1是第二个元素的地址,计算的是地址的大小:4/8
//	printf("sizeof(a[1])\t= %zd\n", sizeof(a[1]));//计算第二个元素的大小
//	printf("sizeof(&a)\t= %zd\n", sizeof(&a));//取出的是数组的地址，计算的是地址的大小:4/8
//	//&a + 1 跳过 16 字节
//	//*&a 解引用访问到16字节
//	//int(*) [4]
//    printf("sizeof(*&a)\t= %zd\n", sizeof(*&a));//16
//	//printf("%zd\n", sizeof(a));
//	//*&a, * 和 & 抵消了，sizeof(a)
//	printf("sizeof(&a + 1)\t= %zd\n", sizeof(&a + 1));//跳过整个数组，指向下一个地址，计算的是地址的大小:4/8
//	printf("sizeof(&a[0])\t= %zd\n", sizeof(&a[0]));//首元素地址大小:4/8
//    printf("sizeof(&a[0] + 1)\t= %zd\n", sizeof(&a[0] + 1));//第二个元素地址大小:4/8
//
//	return 0;
//}


//字符数组
//int main()
//{
//	char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
//    printf("sizeof(arr)\t= %zd\n", sizeof(arr));//6 * 1 = 6 整个数组的大小
//    printf("sizeof(arr + 0)\t= %zd\n", sizeof(arr + 0));//arr就是首元素的地址,arr+0还是首元素的地址,计算的是地址的大小:4/8
//    printf("sizeof(*arr)\t= %zd\n", sizeof(*arr));//计算首元素大小
//    printf("sizeof(arr[1])\t= %zd\n", sizeof(arr[1]));//计算第二个元素大小
//    printf("sizeof(&arr)\t= %zd\n", sizeof(&arr));//取出数组的地址，计算地址的大小:4/8
//    printf("sizeof(&arr + 1)\t= %zd\n", sizeof(&arr + 1));//跳过整个数组，指向下一个地址，计算地址的大小:4/8
//    printf("sizeof(&arr[0] + 1)\t= %zd\n", sizeof(&arr[0] + 1));//第二个元素地址大小:4/8
//
//	return 0;
//}

//int main()
//{
//	char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
//	printf("strlen(arr)\t= %zd\n", strlen(arr));//随机值
//	printf("strlen(arr + 0)\t= %zd\n", strlen(arr + 0));//随机值
//    //printf("strlen(*arr)\t= %zd\n", strlen(*arr));//*arr就是首元素，'a'--> 97. 传给strlen，97会被当作地址，非法访问，程序崩溃
//    //printf("strlen(arr[1])\t= %zd\n", strlen(arr[1]));//第二个元素，arr[1]--> 'b', 同上
//    //printf("strlen(&arr)\t= %zd\n", strlen(&arr));//取出数组的地址，值与首元素相同，依然从首元素开始计算长度到\0，随机值
//    //printf("strlen(&arr + 1)\t= %zd\n", strlen(&arr + 1));//跳过整个数组，指向下一个地址，计算长度到\0，随机值（与上面的差6）
//    printf("strlen(&arr[0] + 1)\t= %zd\n", strlen(&arr[0] + 1));//第二个元素地址，计算长度到\0，随机值
//
//	return 0;
//}


//int main()
//{
//    char arr[] = "abcdef";
//    printf("sizeof(arr)\t= %zd\n", sizeof(arr));//arr表示整个数组，有\0, 7个字节
//    printf("sizeof(arr + 0)\t= %zd\n", sizeof(arr + 0));//首元素地址，arr+0还是首元素的地址 4/8
//    printf("sizeof(*arr)\t= %zd\n", sizeof(*arr));//首元素大小，1字节
//    printf("sizeof(arr[1])\t= %zd\n", sizeof(arr[1]));//第二个元素地址，arr[1]--> 'b', 1字节
//    printf("sizeof(&arr)\t= %zd\n", sizeof(&arr));//整个数组的地址，4/8
//    printf("sizeof(&arr + 1)\t= %zd\n", sizeof(&arr + 1));//跳过数组后的地址，4/8
//    printf("sizeof(&arr[0] + 1)\t= %zd\n", sizeof(&arr[0] + 1));//第二个元素的地址，4/8
//
//	return 0;
//}


//int main()
//{
//    char arr[] = "abcdef";
//    printf("strlen(arr)\t= %zd\n", strlen(arr));//数组首元素地址，6
//    printf("strlen(arr + 0)\t= %zd\n", strlen(arr + 0));//还是数组首元素地址，6
//    //printf("strlen(*arr)\t= %zd\n", strlen(*arr));//*arr就是首元素，'a'--> 97. 传给strlen，97会被当作地址，非法访问，程序崩溃
//    //printf("strlen(arr[1])\t= %zd\n", strlen(arr[1]));//第二个元素，arr[1]--> 'b', 同上
//    //printf("strlen(&arr)\t= %zd\n", strlen(&arr));//取出数组的地址char(*)[7]，值与首元素地址相同，依然从首元素开始计算长度到\0，6
//    //printf("strlen(&arr + 1)\t= %zd\n", strlen(&arr + 1));//跳过整个数组，指向下一个地址，计算长度到\0，随机值
//    printf("strlen(&arr[0] + 1)\t= %zd\n", strlen(&arr[0] + 1));//第二个元素地址，计算长度到\0，5
//
//    return 0;
//}


//int main()
//{
//    const char* p = "abcdef";//常量字符串，把首字符的地址赋给p
//    printf("sizeof(p)\t= %zd\n", sizeof(p));//p是一个指针变量，大小 4/8
//    printf("sizeof(p + 0)\t= %zd\n", sizeof(p + 1));//p+1是 'b' 的地址，大小:4/8
//    printf("sizeof(*p)\t= %zd\n", sizeof(*p));//*p就是首元素，'a', 1字节
//    printf("sizeof(p[1])\t= %zd\n", sizeof(p[0]));//p[0]--> 'a', 1字节
//    printf("sizeof(&p)\t= %zd\n", sizeof(&p));//p指针变量的地址，大小 4/8
//    printf("sizeof(&p + 1)\t= %zd\n", sizeof(&p + 1));//跳过 p 的地址，大小 4/8
//    printf("sizeof(&p[0] + 1)\t= %zd\n", sizeof(&p[0] + 1));//第二个元素地址，大小:4/8
//
//	return 0;
//}


//int main()
//{
//    const char* p = "abcdef";
//    printf("strlen(p)\t= %zd\n", strlen(p));//6 p存放的是首元素地址
//    printf("strlen(p + 0)\t= %zd\n", strlen(p + 1));//5 p+1是 'b' 的地址
//    //printf("strlen(*p)\t= %zd\n", strlen(*p));//非法访问
//    //printf("strlen(p[1])\t= %zd\n", strlen(p[0]));//非法访问
//    //printf("strlen(&p)\t= %zd\n", strlen(&p));//指针变量p的地址，随机值
//    //printf("strlen(&p + 1)\t= %zd\n", strlen(&p + 1));//跳过 p 的地址，随机值
//    printf("strlen(&p[0] + 1)\t= %zd\n", strlen(&p[0] + 1));//5 第二个元素地址
//
//    return 0;
//}


//======================================================================================================================

//二维数组

//int main()
//{
//	int a[3][4] = {
//        {1, 2, 3, 4},
//        {5, 6, 7, 8},
//        {9, 10, 11, 12}
//    };
//    printf("sizeof(a)\t= %zd\n", sizeof(a));//12 * 4 = 48
//    printf("sizeof(a[0][0])\t= %zd\n", sizeof(a[0][0]));//第一行第一个元素 4字节
//    printf("sizeof(a[0])\t= %zd\n", sizeof(a[0]));//第一行的一维数组的数组名 4 * 4 = 16
//    printf("sizeof(a[0] + 1)\t= %zd\n", sizeof(a[0] + 1));//a[0]-->第一行第一个元素的地址，a[0] + 1 --> 第一行第二个元素的地址，4/8
//    printf("sizeof(*(a[0] + 1))\t= %zd\n", sizeof(*(a[0] + 1)));//第一行第二个元素，4字节
//    printf("sizeof(a + 1)\t= %zd\n", sizeof(a + 1));//a-->二维数组首元素地址（第一行的地址），a+1 --> 第二行的地址，4/8
//    printf("sizeof(*(a + 1))\t= %zd\n", sizeof(*(a + 1)));//第二行，4 * 4 = 16  *(a + 1) == a[1]-->第二行数组名，计算第二行的大小
//    printf("sizeof(&a[0] + 1)\t= %zd\n", sizeof(&a[0] + 1));//a[0]-->第一行数组名，&a[0]-->第一行一维数组的地址，&a[0] + 1 -->第二行的地址，4/8
//    printf("sizeof(*(&a[0] + 1))\t= %zd\n", sizeof(*(&a[0] + 1)));//第二行，4 * 4 = 16
//    printf("sizeof(*a)\t= %zd\n", sizeof(*a));//a-->二维数组首元素地址（第一行的地址） 二维数组首元素，第一行大小，4 * 4 = 16  *a == *(a+0) == a[0]
//    printf("sizeof(a[3])\t= %zd\n", sizeof(a[3]));//16  没有越界访问，因为没有访问。
//    //sizeof内部的表达式是不计算的，只是根据类型推导
//
//	return 0;
//}

